﻿#pragma once
#include <stdio.h>
#include <string.h>
//#include <memory.h>
#include <stdint.h>
#include <stdlib.h> // 添加头文件以使用 malloc 和 free

#ifndef MySHA256_H_
#define MySHA256_H_

#pragma pack(push, 1) // 字节对齐
/// <summary>
/// 定义 SHA-256 算法中调试使用的枚举类型
/// </summary>
enum sha256_debug {
    IS_OK = 1,         // 无错误
    INPUT_ERROR = -1,  // 输入参数错误
    MEMORY_ERROR = -2, // 内存分配错误
    FILE_ERROR = -3    // 文件操作错误
};
#pragma pack(pop) // 字节对齐

#define sha256_debug_msg(num) \
    switch (num) { \
        case IS_OK:        printf("No error.\n"); break; \
        case INPUT_ERROR:  printf("Input error.\n"); break; \
        case MEMORY_ERROR: printf("Memory error.\n"); break; \
        case FILE_ERROR:   printf("File error.\n"); break; \
        default:           printf("Unknown error.\n"); break; \
    }


#define SHA256_BLOCK_SIZE 64
#define SHA256_DIGEST_SIZE 32
#define MAX_BUFFER (4096 + 64)
#define DEFAULT_ONCE_SIZE (1024 * 1024 * 2)

#if defined __cplusplus
extern "C" {
#endif // __cplusplus

#include <stdint.h>

    // 定义 SHA-256 算法中使用的结构体
    typedef struct sha256_fileCtx {
        char hash_str_[SHA256_DIGEST_SIZE * 2 + 1]; // 哈希值字符串缓冲区
        char hash_str_buf_[MAX_BUFFER]; // 哈希值缓冲区
        //uint64_t file_size_; // 文件大小
        char* file_buffer_;
        char* file_buffer_copy_;
        size_t   once_size_; // 一次性读入需要计算哈希值的最大字节数
        uint64_t file_position_;  // 文件已计算了哈希值的字节数，如果大于零则需要手动设置哈希值缓冲区 buffer，因为是累计的
        short    buf_index_; // 缓冲区索引位置
    } sha256_fileCtx;

    // 初始化的 sha256_fileCtx 结构体，必须使用 free_sha256_file 释放内存
    char sha256_file_init(sha256_fileCtx* fileCtx, size_t once_size, uint64_t position);
    void free_sha256_fileCtx(sha256_fileCtx* fileCtx);

    // 计算文件 filename 的 SHA-256 哈希值，并将结果保存到 sha256_fileCtx 结构体中
    char file_sha256(sha256_fileCtx* fileCtx, const char* filename);

    // 以下两个函数不建议多线程使用，因为会有全局变量的竞争问题，这里只是测试函数保留的接口，外部使用多线程请考虑线程锁
    // 计算传入的定长字符串的 SHA-256 哈希值，返回 65 字节的哈希值字符串
    const char* strn_to_sha256(const char* input, size_t length);
    // 计算传入的字符串的 SHA-256 哈希值，返回 65 字节的哈希值字符串
    const char* string_to_sha256(const char* input);

    // 打印指定长度的哈希值，其实就是每字节的 2 位十六进制字符串
    void print_hash(const uint8_t* hash, size_t length);

    // 终端打印字符串 "Hello, SHA-256!，this is a test for SHA-256 algorithm." 的 SHA-256 哈希值的 16 进制 65 位字符串
    void test_sha256();


#if defined __cplusplus
}
#endif // __cplusplus

#endif // MySHA256_H
